#ifndef _COMMON_H
#define _COMMON_H


#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/time.h>
#include <math.h>
#include <limits.h>


#define PARAM_PATH "../param"   /**< endereco do arquivo param */
#define TIMER_MSG 60            /**< intervalo entre cada mensagem de status */



/** Estrutura de um job */
typedef struct _job {
    int id;         /**< identificacao (controle interno) */
    int task1;      /**< tempo na maquina 1 */
    int task2;      /**< tempo na maquina 2 */
} Job;


/** Estrutura de um no */
typedef struct _node {
    int id;         /**< identificacao (controle interno) */
    int acc1;       /**< acumulador do tempo na maquina 1 para os scheduled jobs */
    int acc2;       /**< acumulador do tempo na maquina 2 para os scheduled jobs */
    int sft;        /**< sum finishing time dos scheduled jobs */
    int lowBound;   /**< lower bound do no */
    int nSched;     /**< total de scheduled jobs */
    int *sched;     /**< vetor com o schedule dos jobs (job i executado na ordem job[i]) */
} Node;


/** Estrutura utilizada para a resposta */
typedef struct _solution {
    Node *ndSol;        /**< no contendo a melhor solucao encontrada */
    int nNodesChecked;  /**< total de nos explorados */
    int timeElapsed;    /**< tempo total de execucao */
    int primalv;        /**< valor primal */
    int primalt;        /**< tempo de calculo do valor primal */
    int dualv;          /**< valor dual */
    int dualt;          /**< tempo de calculo do valor dual */
} Solution;


/** Estrutura do display */
typedef struct _disp {
    int jobID;      /**< numero do job (ID) */
    int start;      /**< tempo do inicio de execucao */
} Disp;



/** Aloca um espaco de memoria
 * @param size Tamanho do espaco solicitado
 * @return Ponteiro para o espaco alocado
 */
void* memAlloc(const int size);


/** Abre um arquivo
 * @param path Endereco do arquivo
 * @param mode Modo de abertura
 * @return Ponteiro para o arquivo aberto
 */
FILE* openFile(const char *path, const char *mode);


/** Executa um comando pelo terminal
 * @param command Comando solicitado
 */
void execComm(const char *command);


/** Funcao que retorna o maior entre dois inteiros
 * @param a Primeiro valor
 * @param b Segundo valor
 * @return O maior deles
 */
int max(const int a, const int b);


/** Seta o timer para gerar um alarme
 * @param maxExecTime Tempo maximo de execucao (em segundos)
 */
void setTimer(const int maxExecTime);


/** Insere um novo no na fila de prioridade
 * @param queue Vetor contendo a fila
 * @param qSize Tamanho da fila (excluindo o indice 0)
 * @param newNode Node a ser inserido
 */
void queueInsert(Node **queue, int *qSize, Node *newNode);


/** Remove um elemento da fila de prioridade
 * @param queue Vetor contendo a fila
 * @param qSize Tamanho da fila (excluindo o indice 0)
 * @param index Indice do elemento desejado
 * @return Node contido no indice
 */
Node* queueRemove(Node **queue, int *qSize, int const index);


#endif
